﻿using System;
using RabbitMQ.Client;
using Common.Config;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Common.Model;

namespace Common
{
    public class RabbitMQUtil
    {
        public static ConnectionFactory FACTORY = new ConnectionFactory
        {
            HostName = Configs.RabbitHostName,
            UserName = Configs.RabbitUserName,
            Password = Configs.RabbitPassWord,
            //VirtualHost = "my_vhost",
            VirtualHost = Configs.RabbitVirtualHost,//"my_vhost",//注意Rabbitmq配置的虚拟主机,默认为/
            AutomaticRecoveryEnabled = true
        };

        public static void SendMessage(string message)
        {
            SendMessage(message, "track");
        }

        public static void SendMessage(List<string> messages, string quene)
        {
            if (string.IsNullOrEmpty(quene)) return;

            try
            {
                using (var connection = FACTORY.CreateConnection())
                {
                    using (var channel = connection.CreateModel())
                    {
                        bool durable = true;
                        channel.QueueDeclare(quene, durable, false, false, null);
                        var properties = channel.CreateBasicProperties();
                        properties.Persistent = true;
                        messages.ForEach(z =>
                        {
                            var body = Encoding.UTF8.GetBytes(z);
                            channel.BasicPublish("", quene, properties, body);
                        });

                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("写入队列异常： {0} ", ex.Message));
                //NLogHelper.Error("消息队列推送消息失败：" + ex.Message, ex);
            }
        }

        public static void SendMessage(string message, string quene)
        {
            if (string.IsNullOrEmpty(quene)) return;

            try
            {
                using (var connection = FACTORY.CreateConnection())
                {
                    using (var channel = connection.CreateModel())
                    {
                        bool durable = true;
                        channel.QueueDeclare(quene, durable, false, false, null);
                        var properties = channel.CreateBasicProperties();
                        properties.Persistent = true;
                        var body = Encoding.UTF8.GetBytes(message);
                        channel.BasicPublish("", quene, properties, body);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("写入队列异常： {0} ", ex.Message));
                //NLogHelper.Error("消息队列推送消息失败：" + ex.Message, ex);
            }
        }

        /// <summary>
        /// 发送延迟队列
        /// </summary>
        /// <param name="json"></param>
        public static void DelaysQueue(string json, int expires, int ttl_expires)
        {
            try
            {
                using (var connection = FACTORY.CreateConnection())
                {

                    using (var channel = connection.CreateModel())
                    {
                        //int expires = 30 * 60 * 1000;
                        Dictionary<string, object> dic = new Dictionary<string, object>();
                        dic.Add("x-expires", expires);//30000
                        dic.Add("x-message-ttl", ttl_expires);//队列上消息过期时间，应小于队列过期时间  

                        dic.Add("x-dead-letter-exchange", "exchange-direct");//过期消息转向路由  
                        dic.Add("x-dead-letter-routing-key", "routing-delay");//过期消息转向路由相匹配routingkey  
                                                                              //创建一个名叫"zzhello"的消息队列
                        channel.QueueDeclare(queue: "DelaysApproval",
                            durable: true,
                            exclusive: false,
                            autoDelete: false,
                            arguments: dic);

                        var body = Encoding.UTF8.GetBytes(json);

                        //向该消息队列发送消息message
                        channel.BasicPublish(exchange: "",
                            routingKey: "DelaysApproval",
                            basicProperties: null,
                            body: body);
                    }

                }

            }
            catch (Exception ex)
            {
                //NLogHelper.Error("消息队列推送消息失败：" + ex.Message, ex);
            }
        }

        /// <summary>
        /// 写入延迟队列消息
        /// </summary>
        /// <param name="messageList"></param>
        public static void SendMultDelayMessage(List<DelayMessageModel> messageList)
        {

            Task.Run(() =>
            {
                try
                {
                    using (var connection = RabbitMQUtil.FACTORY.CreateConnection())
                    {

                        using (var channel = connection.CreateModel())
                        {
                            Dictionary<string, object> dic = new Dictionary<string, object>();
                            dic.Add("x-delayed-type", "direct");

                            var exchange = "exchange-direct-delay-common";
                            var queue = "lis-delay-quene-common";
                            var routingKey = "routingkey-delay-common";

                            channel.ExchangeDeclare(exchange, "x-delayed-message", true, false, dic);
                            channel.QueueDeclare(queue: queue,
                                 durable: true,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null);
                            channel.QueueBind(queue: queue, exchange: exchange, routingKey: routingKey);

                            foreach (var item in messageList)
                            {
                                if (!string.IsNullOrEmpty(item.CallBackUrl))
                                {
                                    var properties = channel.CreateBasicProperties();
                                    properties.Persistent = true;
                                    properties.Headers = new Dictionary<string, object> {
                                    { "x-delay",item.DelayTime}
                                };

                                    var json = JsonConvert.SerializeObject(item);
                                    var body = Encoding.UTF8.GetBytes(json);
                                    //向该消息队列发送消息message
                                    channel.BasicPublish(exchange: exchange,
                                    routingKey: routingKey,
                                    basicProperties: properties,
                                    body: body);
                                }

                            }
                        }

                    }

                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("写入延迟队列异常： {0} ", ex.Message));
                    //NLogHelper.Error("消息队列推送消息失败：" + ex.Message, ex);
                }
            });
        }

        public static void SendDelayMessage(DelayMessageModel message)
        {
            Task.Run(() =>
            {
                try
                {
                    using (var connection = RabbitMQUtil.FACTORY.CreateConnection())
                    {

                        using (var channel = connection.CreateModel())
                        {
                            Dictionary<string, object> dic = new Dictionary<string, object>();
                            dic.Add("x-delayed-type", "direct");

                            var exchange = "exchange-direct-delay-common";
                            var queue = "lis-delay-quene-common";
                            var routingKey = "routingkey-delay-common";

                            channel.ExchangeDeclare(exchange, "x-delayed-message", true, false, dic);
                            channel.QueueDeclare(queue: queue,
                                 durable: true,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null);
                            channel.QueueBind(queue: queue, exchange: exchange, routingKey: routingKey);


                            var properties = channel.CreateBasicProperties();
                            properties.Persistent = true;
                            properties.Headers = new Dictionary<string, object> {
                                    { "x-delay",message.DelayTime}
                                };

                            var json = JsonConvert.SerializeObject(message);
                            var body = Encoding.UTF8.GetBytes(json);
                            //向该消息队列发送消息message
                            channel.BasicPublish(exchange: exchange,
                                routingKey: routingKey,
                                basicProperties: properties,
                                body: body);


                        }

                    }

                }
                catch (Exception ex)
                {
                    //NLogHelper.Error("消息队列推送消息失败：" + ex.Message, ex);
                }
            });
        }
    }
}
